<html>

<head>
 <link rel="stylesheet" type="text/css" href="doc-styles.css"></link>
 <title>glScript Extensions Reference</title> 
</head>
 
<body>
<h3>glScript Extensions Reference</h3>

<a href="index.html">Index</a>

<h4>Contents</h4>
<ul>
<li><a href="#glscript_extensions_overview">Extensions Overview</a></li>
<li><a href="#glscript_extension_capabilities">Extension Capabilities</a></li>
<li><a href="#gls_sdk">gls SDK</a></li>
<li><a href="#glscript_extension_interfaces">Extension Interfaces</a></li>
<!--
<li>GLSExtension Interface</li>
<li>GLSExtensionHost Interface</li>
<li>_GLScriptExtLib Interface</li>
-->
<li><a href="#glscript_export_functions">Export Functions</a></li>
<li><a href="#glscript_extension_performance_optimization">Performance Optimization</a></li>
</ul>

<a name="glscript_extensions_overview"><h4>Extensions Overview</h4></a>
<p>
glScript extensions are plugins or modules that can be loaded dynamically and used by your scripts.
Extensions are compiled executables that can be easily integrated with glScript engine to 
extend its functionality. Different extensions can provide different capabilities based on requirements. 
<i>Library extension</i>, for example, can provide a set of functions that can be called from your script. 
<i>GUI plugin</i> extension can be loaded in a development application environment to extend its features. 
<i>Renderer extension</i> will provide certain interfaces that allow glScript engine to
draw graphics and perform animations natively rather than through scripts. 
</p>
<p>
You can create your own extensions and use them in your scripts. 
</p>

<!-- Extension Capabilities -->
<a name="glscript_extension_capabilities"><h4>Extension Capabilities</h4></a>
<p>
Capabilities are not different types of extension but various capabilities or features of any extension.
A single extension can support one or more or all of the capabilities.
</p>
<ul>
<li>Library extension</li>
<li>GUI Plugin extension</li>
<li>Renderer extension</li>
</ul>

<h5>Library Extension</h5>
<p>
A library extension, as the name suggests, can provide library of functions that can be accessed from your script. 
They are typically useful for extending the glScript APIs with new set of features that can be accessed from your scripts.
For example, you can implement a library extension that allows you to read data from network or download a file from the
Internet. Since extensions are native / compiled modules, they have access to OS native APIs and can provide a wide range of 
programming support for your scripts. They also offer better performance than scripts in terms of speed. Library extensions 
make it possible for you to add new APIs as libraries using native code and make those APIs easily available to your scripts. 
This capability is specified by setting <code>GLS_EXTENSION_LIBRARY</code> flag in capabilities bitmask.
</p>

<h5>GUI Plugin Extension</h5>
<p>
A GUI plugin extension is meant for use within a development application environment. Their basic purpose is to extend and
add new features to the application dynamically. A GUI plugin will have a UI that will be hosted by the application
within its main window. The actual implementation logic and integration design is a work in progress. In order to support this
capability, you should set <code>GLS_EXTENSION_GUIPLUGIN</code> flag in capabilities bitmask.
</p>

<h5>Renderer Extension</h5>
<p>
A renderer extension provides support for native OpenGL drawing functions and is useful for creating a graphics
and animation library for your scripts. This capability can be specified by setting <code>GLS_EXTENSION_RENDERER</code>
flag in capabilities bitmask.
</p>
<!-- end Extension Capabilities -->

<a name="gls_sdk"><h4>gls SDK</h4></a>
<p>
You will require gls SDK to build your own extensions for glScript engine.
You must have Microsoft Visual Studio 2005 (at least) installed on your system to build your extensions.
gls SDK consists of C/C++ header files that provides support and required interfaces for building your extensions. Following 
table highlights each component and the header files available in the SDK along with their purpose.
</p>
<h5> gls SDK components</h5>
<ul>
<li>
com: <code>com</code> provides support for COM (Component Object Model). Since library extension's interface, also known as extension's
lib interface, is based on COM, you will need this component to build them. This component contains template based header files that 
provides implementations for standard COM interfaces like <code>IDispatch</code> and <code>IClassFactory</code>.
</li>
<li>
glscript: This component contains basic type definitions used by glScript engine and header files necessary for building
extensions.
</li>
</ul>
<h5>gls SDK Header files</h5>
<table border="1" cellpadding="2" cellspacing="2" style="border-top:solid 1px;">
	<tr><th colspan="2">gls_sdk/com/</th></tr>
	<tr>
		<td width="200px">dispatch.h</td> <td>Template classes for IUnknown, IDispatch support</td>
	</tr>
	<tr>
		<td>class_factory.h</td> <td>Template class for IClassFactory support</td>
	</tr>
	<tr>
		<td colspan="2" style="border-bottom:solid 1px;">&nbsp;</td>
	</tr>
	
	<tr><th colspan="2">gls_sdk/glscript/</th></tr>
	<tr>
		<td>gls_types.h</td><td>Basic type definitions and macros used by glScript</td>
	</tr>
	
	<!--
	<tr>
		<td>gls_obj.h</td> <td>Referenced object types used in glScript</td>
	</tr>
	-->
	
	<tr>
		<td>gls_extension.h</td> <td>Main header file for gls extensions</td>
	</tr>
	
	<tr>
		<td>gls_ext_lib.idl</td> <td>IDL file for gls library extensions</td>
	</tr>
	
	<tr>
		<td>gls_ext_lib.h</td> <td>Header file for gls library extensions</td>
	</tr>
	
	<tr>
		<td>gls_ext_lib_i.c</td> <td>Actual definitions of IIDs used in gls_ext_lib.h</td>
	</tr>	
</table>

<p>
Please refer the Doxygen docs for more detailed documentation
<a href="gls-sdk-reference-doxygen/html/index.html" target="_blank">here</a>&nbsp;...
</p>


<!-- Interfaces -->
<a name="glscript_extension_interfaces"><h4>Extension Interfaces</h4></a>

<h5>GLSExtension interface</h5>
<p>
glScript engine communicates with your extension through the <code>GLSExtension</code> interface. This interface allows the engine to
query your extension's capabilities, author's name and other interfaces supported by your extension based on its capabilities.
So, <code>GLSExtension</code> is the entry point interface for glScript engine to your extension's various capabilities. All 
extensions must implement this interface.
</p>
<p>
<code>GLSExtension</code> is a C++ abstract class interface. Please refer the Doxygen docs for detailed documentation
<a href="gls-sdk-reference-doxygen/html/class_g_l_s_extension.html" target="_blank">here</a>&nbsp;...
</p>

<h5>GLSExtensionHost interface</h5>
<p>
Every gls extension is initialized with <code>GLSExtensionHost</code> interface, which provides access to the host environment.
Extensions can use this interface to query information about the running script, version of the loader application, 
etc. The interface also provides various methods that can be used for loading other extensions, hooking timer and render
callback procedures.
</p>
<p>
<code>GLSExtensionHost</code> is a C++ abstract class interface. You are not supposed to implement 
this interface in your extensions. Please refer the Doxygen docs for detailed documentation
<a href="gls-sdk-reference-doxygen/html/class_g_l_s_extension_host.html" target="_blank">here</a>&nbsp;...
</p>

<h5>_GLScriptExtLib interface</h5>
<p>
<code>_GLScriptExtLib</code> is a COM (Component Object Model) automation interface for creating library extensions. You will need
to implement this interface only if you are creating a library extension. <code>_GLScriptExtLib</code> derives from 
<code>IDispatch</code> interface. This allows gls scripts to invoke the interface methods and properties using late-binding in 
their own syntax. For e.g. if you implement this interface, it can be called from JavaScript or VBScript or any other ActiveScript 
based scripting language running within glScript environment.
</p>
<p>
As <code>_GLScriptExtLib</code> is a COM interface, you should create a COM object that implements your library methods. When your 
library extension is loaded by a script using <code>gls.require</code> function, glScript engine loads your extension and 
obtains its <code>GLSExtension</code> interface. It then calls <code>GetLibInterface</code> method on this interface to query for 
the lib interface. You should create your COM object at this point that implemnts the <code>_GLScriptExtLib</code> interface and
return the interface. glScript engine then returns the <code>_GLScriptExtLib</code> interface to the calling script as a result of 
the <code>gls.require</code> call. The calling script should save the interface in some variable and can start invoking its 
methods and properties. The code snippet below shows two steps for using library extensions:
<pre><code>// require the "obj" library extension. This loads the "obj" extension and returns its _GLScriptExtLib interface.
var obj = gls.require ("obj");

// test _GLScriptExtLib properties and methods
console.log ( 
	"libname: " + obj.name + "\r\n" + 
	"version: " + obj.version
	);
</code></pre>

<h5>Creating your own _GLScriptExtLib derived interface</h5>
<p>You usually dont implement the <code>_GLScriptExtLib</code> interface directly but instead derive your own interface and
implement that interface. <code>_GLScriptExtLib</code> interface provides common properties and methods that should be a part
of all gls library extension interfaces. For e.g. all gls library extensions should have a <code>name</code> and <code>version</code>
property that can be accessed from the script. Following IDL code fragment shows an example of <code>_MyLib</code> interface based on 
<code>_GLScriptExtLib</code>.
</p>
<pre><code>[
// interface attributes for _MyLib 
uuid(ab138963-6583-475a-abeb-84800644b1e7),
object,
oleautomation,
nonextensible,
hidden,
helpstring("_MyLib interface")
]
// _MyLib interface
interface _MyLib : _GLScriptExtLib {
	// _MyLib interface methods
	[helpstring("Sum of two numbers")]
	HRESULT sum ([in]short a, [in]short b, [out,retval]short *pRetVal);
}
</code></pre>

<p>
Sample script that uses <code>_MyLib</code> interface assuming "mylib" as the library extension implementing it:
</p>
<pre><code>var mylib = gls.require ("mylib");
console.log ( "libname: " + mylib.name + "\r\n" + "version: " + mylib.version );
console.log ( "4 + 5 = " + mylib.sum(4,5).toString() );
</code></pre>

<h5>Implementing _GLScriptExtLib interface</h5>
<p>
You need to create a COM object that implements your <code>_GLScriptExtLib</code> derived interface. There are many ways of doing
this: in the plain way without any libraries, using libraries like STL (Standard Template Library), or using <i>com</i> library 
that is a part of gls_sdk. This documentation will focus only on gls_sdk com library.
</p>
<p>
gls_sdk <i>com</i> is a very simple and quite adequate library for creating simple COM objects that supports automation.
There are two template classes <code>AutomationComObject</code> and <code>ContainedAutomationComObject</code> for creating 
COM objects. <code>AutomationComObject</code> provides implementations for <code>IUnknown</code> and <code>IDispatch</code> 
interfaces along with support for type library loading from application's resource. Another template class <code>ClassFactory</code> 
provides implementation for <code>IClassFactory</code> and is useful for instantiating your COM objects. You will only require 
<code>AutomationComObject</code> and <code>ClassFactory</code> in most cases.
</p>
<p>
You can implement your COM object by creating a new class dervied from <code>AutomationComObject</code> passing necessary
arguments to the base template class. As obvious, <code>AutomationComObject</code> class takes care of <code>IUnknown</code> and
<code>IDispatch</code> interfaces and type library loading. In your derived class, you need to implement all properties and methods
that are part of <code>_GLScriptExtLib</code> and your own custom library interface.
</p>
<p>
Following example shows how to create a simple COM class named <code>MyLib</code> using gls_sdk that implements 
<code>_GLScriptExtLib</code> and <code>_MyLib</code> interfaces shown in the previous example:
</p>

<pre><code>class MyLib : public AutomationComObject
			&lt;_MyLib, 		// Base interface from which to derive
			_MyLib_IIDs, 		// Array of pointers to interface IDs (IIDs) that MyLib class implements
			&IID__MyLib&gt;		// Main interface IID for which type library is loaded from resource
{
public:
	/* _GLScriptExtLib methods */
	HRESULT STDMETHODCALLTYPE get_name (BSTR *pValue) {
		*pValue = SysAllocString (L"mylib");
		return NOERROR;
	}
	
	HRESULT STDMETHODCALLTYPE get_version (short *pValue) {
		*pValue = GLS_VERISON_MAKE_SHORT(0,1);
		return NOERROR;
	}

	/* _MyLib methods */
	HRESULT STDMETHODCALLTYPE sum (short a, short b, short *pRetVal) {
		*pRetVal = a + b;
		return NOERROR;
	}
};
</code></pre>

<p>
You will usually want a factory object for your <code>MyLib</code> COM class, so you can create its objects at run time.
This can be done by simply creating a global object of <code>ClassFactory</code> with your class name as template argument 
as shown below:
</p>
<pre><code>// factory of MyLib COM objects
extern ClassFactory&lt;MyLib&gt; MyLib_Factory;
</code></pre>

<!-- end Interfaces -->

<!-- Export Functions -->
<a name="glscript_export_functions"><h4>Export Functions</h4></a>
<p>
gls Extensions must export a set of functions so that it can be properly loaded and initialized by glScript engine. These functions
must be exported by name, so that it is possible to get the entry points using names. These functions are:
</p>
<ul>
<li>gls_extension_initialize</li>
<li>gls_extension_terminate</li>
<li>gls_extension_get_interface</li>
</ul>

<h5>Calling Convention</h5>
<p>
All export functions must use <code>GLS_API_CALL</code> as their calling convention.
</p>

<h5>gls_extension_initialize</h5>
<p>
<code>gls_extension_initialize</code> function is called to initialize the extension after it has been loaded. The extension 
should perform initialization in this function. Since this function may be called by a new thread, your extension should take care of 
initializing thread specific data in this function. This function receives a single parameter of type <code>GLSExtensionHost</code>, 
which is the interface to the extension host. Your extension should first check version of the <code>GLSExtensionHost</code> interface 
to make sure you have access to all methods you intend to use. You should then query for host environment type and 
required version of the loader (application / player), if required. If everything is fine, you can continue with initialization of your 
data. You may save the <code>GLSExtensionHost</code> interface on your side for later use. On success, your function should return 
<code>true</code> to indicate your extension has been initialized properly and can be used, otherwise <code>false</code>. If you return 
<code>false</code>, the loader aborts the process and unloads your extension. You should perform necessary cleanup if your extension 
cannot be initialized before it returns.
</p>
<p>
The following example shows a typical implementation of this function without any error handling code:
</p>
<pre><code>// storage type for our TLS (Thread Local Storage) data.
struct TLS_DATA {
  GLSExtensionHost *pExtensionHost;
  GLSExtension *pExtension;
};

// index for our TLS data; must be initialized somewhere before we use it
DWORD _tlsMyData;

// Initialize this extension for current thread
bool GLS_API_CALL gls_extension_initialize (GLSExtensionHost *pExtensionHost) {

  // check for host interface version if required
  if (pExtensionHost->GetInterfaceVersion() >= GLS_VERSION_MAKE_SHORT(0,1))
  {
    // allocate our TLS data for current thread
    TLS_DATA *myData = new TLS_DATA ();
	
    // save extension host inteface for later use
    myData->pExtensionHost = pExtensionHost;
	
    // extension interface to be created later
    myData->pExtension = NULL;
		
    // save the TLS data
    TLSsetValue (_tlsMyData, (LPVOID)myData);
		
    return true; // ok
  }
  
  return false; // initialization failed
}
</code></pre>

<h5>gls_extension_terminate</h5>
<p>
<code>gls_extension_terminate</code> function is called by the engine before it unloads your extension.
You should perform cleanup and release resources allocated by your extension for current thread. Note that 
<code>gls_extension_terminate</code> is never called if your extension failes to initialize i.e. 
<code>gls_extension_initialize</code> returns <code>false</code>.
</p>
<pre><code>// Terminate the extension for current thread
void gls_extension_terminate () 
{
  // get TLS data
  TLS_DATA *pData = (TLS_DATA *)TLSgetValue (_tlsMyData);
	
  // destroy GLSExtension object if required
  if (pData->pExtension) {
    delete pData->pExtension;
  }
	
  // release TLS data
  delete pData;
	
  TLSsetVale (_tlsMyData, NULL);
}
</code></pre>

<h5>gls_extension_get_interface</h5>
<p>
<code>gls_extension_get_interface</code> function is called by the engine to get an interface to your extension.
Your extension should use different instances of <code>GLSExtension</code> objects for each calling thread unless your object 
is thread safe. A singleton <code>GLSExtension</code> object can be reused or shared per thread.
</p>
<pre></code>// Return the extension interface to the engine
GLSExtesnsion *gls_extension_get_interface ()
{
  // get TLS data
  TLS_DATA *pData = (TLS_DATA *)TLSgetValue (_tlsMyData);  
  
  // create only if required
  if (pData->pExtension == NULL) {
    pData->pExtension = new MyExtension (pData->pExtensionHost);
  }
  
  // return the interface
  return pData->pExtension;
}
</code></pre>
<!-- end Export Functions -->

<!-- Performance Optimization -->
<a name="glscript_extension_performance_optimization"><h4>Performance Optimization</h4></a>
<p>
This section provides some notes on performance optimization if you are creating an extension as 
a Windows DLL module.
</p>
<p>
DLLs can define a <code>DllMain</code> entry point, which is called when the DLL
is first mapped with the executable process. It is also called each time a thread is attached 
or detached to the process.
<code>DLL_THREAD_ATTACH</code> and <code>DLL_THREAD_DETACH</code> calls can be used 
to perform thread level tracking of data. Since, gls extensions use their own export functions 
<code>gls_extension_initialize</code> and <code>gls_extension_terminate</code> to achieve the same, 
these extra calls can be disabled by calling <code>DisableThreadLibraryCalls</code> Win32 API as
shown below:
</p>
<p>
<pre><code>BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
  if (fdwReason == DLL_PROCESS_ATTACH) {
    _hAppInstance = hinstDLL;

    ::DisableThreadLibraryCalls ( (HMODULE)hinstDLL );
  }

  return TRUE;
}
</code></pre>
</p>
<!-- end Performance Optimization -->

<div class="footer">
OpenGL is a registered trademark of Silicon Graphics, Inc.
</div>
</body>
</html>
